#ifndef LEDDAYDRIVER_H
#define LEDDAYDRIVER_H
#include "softwarePwm.h"
#define UPDATE_PERIOD 1000
#define MILLISINDAY 86400000
struct DayParams
{
unsigned char min;
unsigned char max;
unsigned long daystarttime;
unsigned long daylengthtime;
unsigned long timeAdj;
};

class LEDDayDriver : public TimerEventListener
{
public:
    LEDDayDriver( TimerQueue& militimer, TimerQueue& microtimer, DayParams day, PWMParams pwm)
        :ledpin(microtimer, pwm),
          timer(militimer), minstate(day.min),maxstate(day.max), daystart(day.daystarttime), daylength(day.daylengthtime), timeAdjustment(day.timeAdj)

    {
        adjustPwm();
        timer.registerTimerEvent(this,UPDATE_PERIOD);
    }
    unsigned long onTime()
    {
        adjustPwm();
        return UPDATE_PERIOD;
    }
    void configUpdate(DayParams& day)
    {
         minstate = day.min;
         maxstate = day.max;
         daystart = day.daystarttime;
         daylength = day.daylengthtime;
         if(day.timeAdj != 0)
           timeAdjustment = day.timeAdj;
    }
private:
    void adjustPwm()
    {
        unsigned char newState = minstate;
        unsigned long currentTime = (millis()+timeAdjustment)%MILLISINDAY;//modulo miliseconds in 24h
        if(currentTime < daystart+daylength && currentTime > daystart)
        {
             newState = minstate+(maxstate-minstate)*(((-1.*cos(2.*PI * (double)(currentTime - daystart)/(double)daylength))+1)/2);
        }
        if(newState != currentState)
        {
          ledpin.setPWM(newState);
          if(newState==0)
            ledpin.stop();
          if(currentState==0)
            ledpin.start();  
          currentState = newState;
        }


    }
    Pwm ledpin;
    TimerQueue& timer;
    unsigned char minstate;
    unsigned char maxstate;
    unsigned char currentState;
    unsigned long daystart;
    unsigned long daylength;
    unsigned long timeAdjustment;//how many millis there was since hour 0:00, and program start
};

#endif // LEDDAYDRIVER_H
